package com.wzdigit.wms.raw.service.transfer;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.framework.utils.BeanCopyUtil;
import com.wzdigit.mes.basic.api.BasicSimpleCodeRuleApi;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.transfer.CommitTransferReq;
import com.wzdigit.wms.basic.client.request.transfer.SearchTransferManageRequest;
import com.wzdigit.wms.basic.client.request.transfer.SearchTransferTaskRequest;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.basic.LocationResponse;
import com.wzdigit.wms.basic.client.response.transfer.*;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.basic.Warehouse;
import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.GoodsLog;
import com.wzdigit.wms.basic.domain.inventory.InvTrans;
import com.wzdigit.wms.basic.domain.inventory.Lotno;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.order.TrsnDtl;
import com.wzdigit.wms.basic.domain.order.TrsnDtlGoods;
import com.wzdigit.wms.basic.domain.order.TrsnHeader;
import com.wzdigit.wms.basic.domain.transfer.*;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.enums.operate.OperateCodeEnum;
import com.wzdigit.wms.basic.mapper.core.basic.LocationMapper;
import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;
import com.wzdigit.wms.basic.mapper.core.basic.WarehouseMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsLogMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.mapper.core.order.TrsnDtlGoodsMapper;
import com.wzdigit.wms.basic.mapper.core.order.TrsnDtlMapper;
import com.wzdigit.wms.basic.mapper.core.order.TrsnHeaderMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.*;
import com.wzdigit.wms.basic.service.code.InventoryService;
import com.wzdigit.wms.basic.util.DateUtils;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.basic.util.StringUtils;
import com.wzdigit.wms.common.entity.CommonProperty;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.common.utils.HttpExcel;
import com.wzdigit.wms.common.utils.MyListUtil;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnEnums;
import com.wzdigit.wms.raw.mapper.transfer.TransferAutoMapper;
import com.wzdigit.wms.raw.service.backtosap.TransferAutoBackService;
import com.wzdigit.wms.raw.service.wmscommon.core.GoodsService;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 原材料调拨任务Service
 * Created by zyf on 2021/8/11 23:33
 */
@Service
@Slf4j
public class TransferAutoService {
    private static final String GDN_D16="GDN_D16";
    private static final String  TRSN_ORDER="TRSN_ORDER";
    public static List<String> transferTypeList;	// 调拨类型
    public static List<Integer> transferStatusList;	// 调拨状态
    public static List<Integer> transferAllStatusList;	// 调拨全部状态
    static{
        transferTypeList = new ArrayList<String>(2);
        transferTypeList.add(TransferTypeEnum.T07.code);
        transferTypeList.add(TransferTypeEnum.T08.code);
    }
    static{
        transferStatusList = new ArrayList<Integer>(4);
        transferStatusList.add(TransferHeaderStatusEnum.CREATE.code);
        transferStatusList.add(TransferHeaderStatusEnum.HASDONE.code);
        transferStatusList.add(TransferHeaderStatusEnum.DOING.code);
        transferStatusList.add(TransferHeaderStatusEnum.FINISH.code);
    }
    static{
        transferAllStatusList = new ArrayList<Integer>(6);
        transferAllStatusList.add(TransferHeaderStatusEnum.CANCEL.code);
        transferAllStatusList.add(TransferHeaderStatusEnum.CREATE.code);
        transferAllStatusList.add(TransferHeaderStatusEnum.HASDONE.code);
        transferAllStatusList.add(TransferHeaderStatusEnum.DOING.code);
        transferAllStatusList.add(TransferHeaderStatusEnum.FINISH.code);
        transferAllStatusList.add(TransferHeaderStatusEnum.CLOSE.code);
    }

    @Autowired
    private TransferHeaderMapper transferHeaderMapper;
    @Autowired
    private TransferDtlMapper transferDtlMapper;
    @Autowired
    private TransferDtlGoodsMapper transferDtlGoodsMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private LocationMapper locationMapper;
    @Autowired
    private TransferAutoMapper transferAutoMapper;
    @Autowired
    private GdnHeaderMapper gdnHeaderMapper;
    @Autowired
    private GdnDtlMapper gdnDtlMapper;
    @Autowired
    private TrsnHeaderMapper trsnHeaderMapper;
    @Autowired
    private TrsnDtlMapper trsnDtlMapper;
    @Autowired
    private TrsnDtlGoodsMapper trsnDtlGoodsMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private GoodsLogMapper goodsLogMapper;

    @Reference(version = "${dubbo.consumers.basic.simple.code.rule.api:1.0.0}", check = false)
    BasicSimpleCodeRuleApi basicSimpleCodeRuleApi;

    @Lazy
    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private TransferAutoBackService transferAutoBackService;


    //调拨提交关单回传SAP
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result backTranSap(Integer headerId, HttpServletRequest servletRequest){
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        TransferHeader header =
                transferHeaderMapper.selectOne(new QueryWrapper<TransferHeader>().eq("TRANSFER_HEADER_ID", headerId));
        if (header.getStatus().equals(TransferHeaderStatusEnum.CLOSE.code)){
            Shift.fatal("该调拨单已关闭!");
        }
        List<TransferDtl> dtlList = transferDtlMapper.
                selectList(new QueryWrapper<TransferDtl>().
                        eq("TRANSFER_HEADER_ID", headerId).eq("STATUS",
                        TransferDtlStatusEnum.CLOSE.getCode()));
       //至少一个明细关闭才能关闭调拨单
        if (CollectionUtil.isEmpty(dtlList)){
            Shift.fatal("请至少完成一次调拨任务!");
        }
        //回传SAP并把调拨单
        //报废调拨特殊处理

        //更新主档和明细状态为关闭
        Date nowDate=new Date();
        transferAutoMapper.updateHeader(headerId,TransferHeaderStatusEnum.CLOSE.code,loginName,nowDate );
        transferAutoMapper.updateDtl(headerId,TransferDtlStatusEnum.CLOSE.code,loginName,nowDate );

/*
        //出库凭证
        TrsnHeader trsnFmHeader=new TrsnHeader();
        //入库凭证
        TrsnHeader trsnToHeader=new TrsnHeader();
        TrsnDtl trsnDtl=new TrsnDtl();
        TrsnDtlGoods trsnDtlGoods=new TrsnDtlGoods();
        List<TransferDtlGoods> goodsList=new ArrayList<>();
        Integer fmTrsnDtlId;
        Integer toTrsnDtlId;
        int countTrsn=1;
        this.setFmTrsnHeader(header,dtlList.get(0),trsnFmHeader,loginName);
        this.setToTrsnHeader(header,dtlList.get(0),trsnToHeader,loginName);
        trsnHeaderMapper.insert(trsnFmHeader);
        trsnHeaderMapper.insert(trsnToHeader);
        Date trsnDate=new Date();
        for (TransferDtl dtl : dtlList) {
            trsnDtl.setTrsnHeaderId(trsnFmHeader.getTrsnHeaderId());
            trsnDtl.setNoteNo(trsnFmHeader.getNoteNo());
            trsnDtl.setNoteLineNo(countTrsn+"");
            trsnDtl.setFmDoc(trsnFmHeader.getFmDoc());
            trsnDtl.setFmDocLine(dtl.getTransferLineNo());
            trsnDtl.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.OUT.code);
            trsnDtl.setSkuId(dtl.getFmSku());
            trsnDtl.setQty(new BigDecimal(dtl.getCmpQty()));
            trsnDtl.setUnit(dtl.getUnit());
            trsnDtl.setInvAttr(dtl.getFmInvAttr());
            trsnDtl.setQaStatus(dtl.getFmQaStatus());
            trsnDtl.setStatus(TrsnDtlStatusEnum.CMP.code);
            trsnDtl.setComments(header.getTransferNo()+"调拨");
            trsnDtl.setCreateUser(loginName);
            trsnDtl.setCreateTime(trsnDate);
            trsnDtlMapper.insert(trsnDtl);
            fmTrsnDtlId=trsnDtl.getTrsnDtlId();
            trsnDtl.setNoteNo(trsnToHeader.getNoteNo());
            trsnDtl.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.IN.code);
            trsnDtl.setSkuId(dtl.getToSku());
            trsnDtl.setInvAttr(dtl.getToInvAttr());
            trsnDtl.setQaStatus(dtl.getToQaStatus());
            trsnDtlMapper.insert(trsnDtl);
            toTrsnDtlId=trsnDtl.getTrsnDtlId();
            goodsList = dtlGoodsMap.get(dtl.getTransferDtlId());
            for (TransferDtlGoods goods : goodsList) {
                trsnDtlGoods.setTrsnDtlId(fmTrsnDtlId);
                trsnDtlGoods.setGoodsSn(goods.getGoodsSn());
                trsnDtlGoods.setGoodsId(goods.getGoodsId());
                trsnDtlGoods.setQty(goods.getQty());
                trsnDtlGoods.setQaStatus(dtl.getFmQaStatus());
                trsnDtlGoods.setComments(header.getTransferNo()+"调拨");
                trsnDtlGoods.setStatus(TrsnDtlGoodsStatusEnum.RECEIVED.getCode());
                trsnDtlGoods.setCreateUser(loginName);
                trsnDtlGoods.setCreateTime(trsnDate);
                trsnDtlGoodsMapper.insert(trsnDtlGoods);
                trsnDtlGoods.setTrsnDtlId(toTrsnDtlId);
                trsnDtlGoods.setQaStatus(dtl.getToQaStatus());
                trsnDtlGoodsMapper.insert(trsnDtlGoods);
            }
            countTrsn++;
        }
*/

        //生成出库单
        if (header.getTransferType().equals(TransferTypeEnum.T08.code)){
            GdnHeader gdnHeader=new GdnHeader();
            GdnDtl gdnDtl=new GdnDtl();
            int count=1;
            Date gdnDate=new Date();
            setGdnHeader(gdnHeader,header,dtlList.get(0),loginName);
            gdnHeaderMapper.insert(gdnHeader);
            for (TransferDtl dtl : dtlList) {
                gdnDtl.setGdnHeaderId(gdnHeader.getGdnHeaderId());
                gdnDtl.setGdnLineNo(count);
                gdnDtl.setWhsId(header.getToWhs());
                gdnDtl.setSkuId(dtl.getToSku());
                gdnDtl.setVendor(dtl.getToVendor());
                gdnDtl.setPoNo(dtl.getToPo());
                gdnDtl.setSoNo(dtl.getToSoNo());
                gdnDtl.setSoLineNo(dtl.getToSoLineNo());
                gdnDtl.setOrderQty(new BigDecimal(dtl.getCmpQty()));
                gdnDtl.setUnit(dtl.getUnit());
                gdnDtl.setInvAttr(dtl.getToInvAttr());
                gdnDtl.setQaStatus(dtl.getToQaStatus());
                gdnDtl.setStatus(GdnDtlStatusEnum.CREATE.code);
                gdnDtl.setCreateTime(gdnDate);
                gdnDtl.setCreateUser(loginName);
                gdnDtl.setSourceShipNotice(header.getTransferNo());
                gdnDtl.setSourceShipNoticeItem(dtl.getTransferLineNo());
                gdnDtlMapper.insert(gdnDtl);
                count++;
            }

        }
        transferAutoBackService.outStoreAsnWriteBack(header,dtlList,header.getTransferType());

//        Shift.fatal("///////////");

        return new  Result<>("关单成功!");
    }



    /**
     * 调拨任务列表
     *
     * @param dto
     * @return
     */
    public PagerInfo<List<TransferTaskResponse>> searchTransferTask(
            SearchTransferTaskRequest dto, Pager<?> pager) {
        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<List<TransferTaskResponse>> pagerInfo = new PagerInfo<>();

        if (dto.getTransferDeptName() != null) {
            dto.setTransferDeptName(StringUtils.decode(dto.getTransferDeptName()));
        }
        List<TransferTaskResponse> list = transferHeaderMapper.getListTransferTask(dto,
                transferTypeList, transferStatusList);
        pagerInfo.setItems(list);
        pagerInfo.setTotalCount(page.getTotal());
        return pagerInfo;
    }

    /**
     * 调拨任务明细
     *
     * @param transferHeaderId
     * @return
     */
    public List<TransferTaskDtlResponse> searchTransferTaskDtl(
            Integer transferHeaderId) {
        List<TransferTaskDtlResponse> listTransferTaskDtl = transferDtlMapper.getListTransferTaskDtl(transferHeaderId);

        //根据行号排个序
        listTransferTaskDtl = listTransferTaskDtl.stream().sorted(Comparator.comparing(TransferTaskDtlResponse::getTransferLineNo)).collect(Collectors.toList());

        return listTransferTaskDtl;
    }

    /**
     * 获取调拨单明细
     *
     * @param transferDtlId
     * @param transferLineNo
     * @param servletRequest
     * @param servletResponse
     */
    public TransferDtlResp getTransferTaskDtl(Integer transferDtlId,
                                              String transferLineNo,
                                              String transferNo,
                                              HttpServletRequest servletRequest,
                                              HttpServletResponse servletResponse) {
        QueryWrapper<TransferDtl> transferDtlQueryWrapper = new QueryWrapper<>();
        transferDtlQueryWrapper.eq("TRANSFER_DTL_ID", transferDtlId);
        transferDtlQueryWrapper.eq("TRANSFER_LINE_NO", transferLineNo);
        transferDtlQueryWrapper.eq("TRANSFER_NO", transferNo);
        TransferDtl transferDtl = transferDtlMapper.selectOne(transferDtlQueryWrapper);
        if (transferDtl == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "未查询到相关记录");
        }
        TransferDtlResp transferDtlResp = new TransferDtlResp();
        BeanUtils.copyProperties(transferDtl, transferDtlResp);
        //设置物料编码
        Integer fmSku = transferDtlResp.getFmSku();
        if (fmSku == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "单据明细不存在物料编码信息");
        }
        Sku sku = skuMapper.selectById(fmSku);
        transferDtlResp.setMaterialCode(sku.getSkuCode());
        transferDtlResp.setSkuCode(sku.getSkuCode());
        transferDtlResp.setSkuDesc(sku.getDescCn());
        //设置客户机型
        transferDtlResp.setModel(sku.getModel());
        TransferHeader transferHeader = transferHeaderMapper.selectById(transferDtl.getTransferHeaderId());
        //设置仓库
        Integer fmWhs = transferHeader.getFmWhs();
        if (fmWhs == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "单据不存在转出仓信息");
        }
        transferDtlResp.setWhsId(fmWhs);
        Warehouse warehouse = warehouseMapper.selectById(fmWhs);
        if (warehouse == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "未根据FM_WHS找到对应仓库，请核实单据信息");
        }

        String whsName = warehouse.getWhsName();
        transferDtlResp.setWarehouse(whsName);
        //设置来源仓库
        transferDtlResp.setFmWhs(fmWhs);
        transferDtlResp.setFmWhsDesc(whsName);
        //设置目标仓
        Integer toWhs = transferHeader.getToWhs();
        if (toWhs == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "单据不存在转入仓信息");
        }
        Warehouse warehouseTarget = warehouseMapper.selectById(toWhs);
        transferDtlResp.setToWhs(toWhs);
        transferDtlResp.setToWhsDesc(warehouseTarget.getWhsName());

        //设置状态
        TransferDtlStatusEnum transferDtlStatusEnum = TransferDtlStatusEnum.getEnumByCode(transferDtlResp.getStatus());
        transferDtlResp.setStatusDesc(transferDtlStatusEnum.getEnumName());

        //设置完成数
        if (Objects.equals(transferDtl.getCmpQty(), null)) {
            transferDtlResp.setCmpQty(0);
        }
        return transferDtlResp;
    }

    /**
     * 扫描SN
     *
     * @param sn
     * @param transferDtlId
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    public Result<TransferTaskScanSnResponse> scanSn(String sn, Integer transferDtlId, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {

        Goods goods = this.goodsMapper.selectOne(new QueryWrapper<Goods>().eq("GOODS_SN", sn));;

        if (goods == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "未查询到该条码相关信息");
        }
        if (goods.getIsHold()!=null){
            if (goods.getIsHold().equals(IsHoldEnum.Yes.code)){
                Shift.fatal("SN["+goods.getGoodsSn()+"]已冻结，无法调拨!");
            }
        }

        int waitUpCode = GoodsStatusEnum.WAIT_UP.getCode();//待上架
        int hasUpCode = GoodsStatusEnum.HAS_UP.getCode();//已上架
        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();//已上架 todo 后面加的

        if (!(goods.getStatus().equals(waitUpCode) || goods.getStatus().equals(hasUpCode) || goods.getStatus().equals(waitDowmCode))) {
            GoodsStatusEnum statusEnum = GoodsStatusEnum.getEnumByCode(goods.getStatus());

            String message = String.format("该条码的状态:【%s】不允许调拨", statusEnum.getEnumName());
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }

        TransferDtl transferDtl = transferDtlMapper.selectOne(new QueryWrapper<TransferDtl>().
                eq("TRANSFER_DTL_ID", transferDtlId));

        if (transferDtl.getStatus().equals(TransferDtlStatusEnum.CLOSE.code)){
            Shift.fatal("明细已关闭，无法扫码");
        }


        TransferHeader transferHeader = transferHeaderMapper.selectById(transferDtl.getTransferHeaderId());

        //校验码调拨单内容与SN信息是否一致
        checkSnEqualTransfer(goods, transferDtl, transferHeader);

        Sku sku = skuMapper.selectById(goods.getSkuId());
        if (sku == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "该条码未在货品主数据中维护");
        }

        TransferTaskScanSnResponse taskScanSnResponse = new TransferTaskScanSnResponse();
        taskScanSnResponse.setSn(goods.getGoodsSn());
        taskScanSnResponse.setPo(goods.getPoNo());
        taskScanSnResponse.setSkuCode(sku.getSkuCode());
        taskScanSnResponse.setQty(goods.getQty());
        taskScanSnResponse.setModel(sku.getModel());
        taskScanSnResponse.setSkuDesc(sku.getDescCn());

        Result<TransferTaskScanSnResponse> result = new Result<>();
        result.setData(taskScanSnResponse);


        return result;
    }


    /**
     * 获取已经扫描的记录
     * 查询 调拨单明细 对应的 调拨明细货品清单(WMS_TRANSFER_DTL_GOODS)
     *
     * @param transferDtlId
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    public Result<List<TransferTaskScanSnResponse>> getCommitedSncanSn(Integer transferDtlId, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {

        Result<List<TransferTaskScanSnResponse>> result = new Result<>();

        //清单集合，
        List<TransferDtlGoods> transferDtlGoodsList = transferDtlGoodsMapper.
                selectList(new QueryWrapper<TransferDtlGoods>().eq("TRANSFER_DTL_ID", transferDtlId));
        if (transferDtlGoodsList.size() == 0) {
            return result;
        }

        List<TransferTaskScanSnResponse> transferTaskScanSnResponseList = new ArrayList<>();

        for (TransferDtlGoods transferDtlGoods : transferDtlGoodsList) {
            TransferTaskScanSnResponse transferTaskScanSnResponse = new TransferTaskScanSnResponse();
            transferTaskScanSnResponse.setSn(transferDtlGoods.getGoodsSn());
            transferTaskScanSnResponse.setQty(transferDtlGoods.getQty());

            transferTaskScanSnResponseList.add(transferTaskScanSnResponse);
        }

        List<String> snList = transferDtlGoodsList.stream().map(s -> s.getGoodsSn()).collect(Collectors.toList());

        List<Goods> goodsList = new ArrayList<>();
        if (snList.size() > 999) {
            List<List<String>> splitList = MyListUtil.splitList(snList, 999);

            for (List<String> split : splitList) {
                List<Goods> goodsSplitList = this.goodsMapper.
                        selectList( new QueryWrapper<Goods>().in("GOODS_SN", split));
                goodsList.addAll(goodsSplitList);
            }
        } else {
            goodsList = this.goodsMapper.
                    selectList( new QueryWrapper<Goods>().in("GOODS_SN", snList));
        }

        for (TransferTaskScanSnResponse transferTaskScanSnResponse : transferTaskScanSnResponseList) {
            for (Goods goods : goodsList) {
                if (goods.getGoodsSn().equals(transferTaskScanSnResponse.getSn())) {
                    transferTaskScanSnResponse.setPo(goods.getPoNo());//设置订单号
                    transferTaskScanSnResponse.setSkuId(goods.getSkuId());//设置SKU_ID
                }
            }
        }

        List<Integer> skuIdList = transferTaskScanSnResponseList.stream().filter(s -> s.getSkuId() != null).map(s -> s.getSkuId()).distinct().collect(Collectors.toList());
        List<Sku> skuList = skuMapper.selectList(new QueryWrapper<Sku>().in("SKU_ID",skuIdList));

        for (TransferTaskScanSnResponse transferTaskScanSnResponse : transferTaskScanSnResponseList) {
            for (Sku sku : skuList) {
                if (sku.getSkuId().equals(transferTaskScanSnResponse.getSkuId())) {
                    transferTaskScanSnResponse.setSkuCode(sku.getSkuCode());//物料编码
                    transferTaskScanSnResponse.setModel(sku.getModel());//机型
                    transferTaskScanSnResponse.setSkuDesc(sku.getDescCn());//描述
                }
            }
        }

        result.setData(transferTaskScanSnResponseList);

        return result;
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Integer> commitTransfer(CommitTransferReq commitTransferReq, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception {
        //调拨单类型
        String transferType = commitTransferReq.getTransferType();
        if (!(TransferTypeEnum.T07.code.equals(transferType)||TransferTypeEnum.T08.code.equals(transferType))){
            Shift.fatal("调拨单据类型错误，无法调拨!");
        }
        Result<Integer> result = new Result<>();

        //调拨单明细
        Long transferDtlId = commitTransferReq.getTransferDtlId();
        TransferDtl transferDtl =  transferDtlMapper.selectOne(new QueryWrapper<TransferDtl>().eq("TRANSFER_DTL_ID", transferDtlId));
        if (transferDtl.getStatus().equals(TransferDtlStatusEnum.CLOSE.getCode())) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "关闭的单据不能重复提交");
        }
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
//        String loginName = "gxm";
        Date nowDate = new Date();

        //待上架
        int waitUpCode = GoodsStatusEnum.WAIT_UP.getCode();
        //已上架
        int hasUpCode = GoodsStatusEnum.HAS_UP.getCode();
        //已下架
        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();

        List<String> snList = commitTransferReq.getSnList();
        List<Goods> goodsList = new ArrayList<>();
        if (snList.size() > 999) {
            List<List<String>> splitList = MyListUtil.splitList(snList, 999);
            for (List<String> split : splitList) {
                if (split != null && split.size() > 0) {
                    List<Goods> goodsSplitList = goodsMapper.selectList(new QueryWrapper<Goods>().in("GOODS_SN", split));
                    goodsList.addAll(goodsSplitList);
                }
            }
        } else {
            goodsList = goodsMapper.selectList(new QueryWrapper<Goods>().in("GOODS_SN", snList));
        }

        if (goodsList.size() == 0) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "提交的SN数量为0");
        }

        Integer allowCount = Math.toIntExact(goodsList.stream().map(s -> s.getStatus())
                .filter(s -> Objects.equals(s, waitUpCode) || Objects.equals(s, hasUpCode)|| Objects.equals(s, waitDowmCode))
                .count());
        if (!allowCount.equals(goodsList.size())) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "录入的条码存在非【待上架】、【已上架】、【已下架】状态的记录");
        }

        //调拨单单头
        TransferHeader transferHeader = transferHeaderMapper.selectById(transferDtl.getTransferHeaderId());
        if (transferHeader.getStatus().equals(TransferDtlStatusEnum.CREATE.getCode())) {
            log.info("调拨单头的状态是:【新建】，更新为【进行中】");
            TransferHeader transferHeaderUpdate = new TransferHeader();
            transferHeaderUpdate.setStatus(TransferDtlStatusEnum.DOING.getCode());
            transferHeaderUpdate.setTransferHeaderId(transferHeader.getTransferHeaderId());
            transferHeaderUpdate.setModifyUser(loginName);
            transferHeaderUpdate.setModifyTime(nowDate);
            int row = transferHeaderMapper.updateById(transferHeaderUpdate);
            log.info("成功更新{}条记录", row);
        }

        //货品主键集合
        List<Integer> goodsIdList = goodsList.stream().map(s -> s.getGoodsId()).collect(Collectors.toList());

        /*
            TODO 不同仓库调拨(库内不同仓库调拨，其余走移库功能)，同时改变库存
            TODO 报废调拨，生成调拨单+出库单，不改变库存，走拣货+交接进行出库
         */
        if (transferType.equals(TransferTypeEnum.T07.getCode())) {
            if (transferHeader.getToWhs()==null){
                Shift.fatal("调拨仓库不存在!");
            }
            if (warehouseMapper.selectByPrimaryKey(transferHeader.getToWhs())==null){
                Shift.fatal("调拨仓库未配置信息!");
            }
            whsUpdateRepertory(loginName,new Date(),goodsList,transferHeader,transferDtl,transferType);
        } else if (transferType.equals(TransferTypeEnum.T08.getCode())) {
            if (transferHeader.getToWhs()==null){
                Shift.fatal("调拨仓库不存在!");
            }
            if (warehouseMapper.selectByPrimaryKey(transferHeader.getToWhs())==null){
                Shift.fatal("调拨仓库未配置信息!");
            }
            whsUpdateRepertory(loginName,new Date(),goodsList,transferHeader,transferDtl,transferType);
            //生成出库单头，改到关单那

        }

        /**
         * 提交的货品，写入调拨货品表
         */
        for (Goods goods : goodsList) {
            TransferDtlGoods transferDtlGoods = new TransferDtlGoods();
            transferDtlGoods.setCreateUser(loginName);
            transferDtlGoods.setCreateTime(nowDate);
            transferDtlGoods.setGoodsId(goods.getGoodsId());
            transferDtlGoods.setGoodsSn(goods.getGoodsSn());
            transferDtlGoods.setQty(goods.getQty());
            transferDtlGoods.setTransferDtlId(transferDtlId);
            transferDtlGoods.setStatus(TransferDtlGoodStatusEnum.HAS_RECEIVE.getCode());
            transferDtlGoods.setQaStatus(goods.getQaStatus());
            transferDtlGoodsMapper.insert(transferDtlGoods);
        }

        //5)更新调拨单明细行的状态为 关闭(5)
        TransferDtl transferDtlUpdate = new TransferDtl();
        BigDecimal countQty = goodsList.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
        transferDtlUpdate.setCmpQty(countQty.intValue());
        transferDtlUpdate.setTransferDtlId(transferDtlId).setStatus(TransferDtlStatusEnum.CLOSE.getCode());
        transferDtlUpdate.setModifyTime(nowDate);
        transferDtlUpdate.setModifyUser(loginName);
        transferDtlMapper.updateById(transferDtlUpdate);

        //这里到后面再关闭
        //6)当调拨单明细行状态都变成 关闭(5) 时，主档状态自动变为 关闭（5）。同时弹出提示框，是否返回【调拨任务】页面
        //List<TransferDtl> transferDtlList = transferDtlMapper.selectList(new QueryWrapper<TransferDtl>().eq("TRANSFER_HEADER_ID",transferHeader.getTransferHeaderId() ));
        //明细已关闭的集合
        //Integer closeCount = Math.toIntExact(transferDtlList.stream().map(s -> s.getStatus()).filter(s -> Objects.equals(s, TransferDtlStatusEnum.CLOSE.getCode())).count());
     /*   if (closeCount.equals(transferDtlList.size())) {
            TransferHeader header = new TransferHeader();
            header.setTransferHeaderId(transferHeader.getTransferHeaderId());
            header.setStatus(TransferHeaderStatusEnum.CLOSE.getCode());
            header.setModifyTime(nowDate);
            header.setModifyUser(loginName);
            //主档状态自动变为 关闭（5）
            transferHeaderMapper.updateById(header);
            log.info(header.toString());
            result.setData(CommonProperty.COMMON_TRUE);//设置返回标识


            //TODO  这里不加回传SAP的代码，关闭调拨单再回传
        }*/
        //TODO 这里生成出库凭证&入库凭证
        TrsnHeader trsnFmHeader=new TrsnHeader();
        TrsnHeader trsnToHeader=new TrsnHeader();
        TrsnDtl trsnDtl=new TrsnDtl();
        TrsnDtlGoods trsnDtlGoods=new TrsnDtlGoods();
        List<TransferDtlGoods> trsnGoodsList=new ArrayList<>();
        Integer fmTrsnDtlId;
        Integer toTrsnDtlId;
        Date trsnDate=new Date();
        int countTrsn=1;
        this.setFmTrsnHeader(transferHeader,transferDtl,trsnFmHeader,loginName);
        this.setToTrsnHeader(transferHeader,transferDtl,trsnToHeader,loginName);
        trsnHeaderMapper.insert(trsnFmHeader);
        trsnHeaderMapper.insert(trsnToHeader);
        trsnDtl.setTrsnHeaderId(trsnFmHeader.getTrsnHeaderId());
        trsnDtl.setNoteNo(trsnFmHeader.getNoteNo());
        trsnDtl.setNoteLineNo(countTrsn+"");
        trsnDtl.setFmDoc(trsnFmHeader.getFmDoc());
        trsnDtl.setFmDocLine(transferDtl.getTransferLineNo());
        trsnDtl.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.OUT.code);
        trsnDtl.setSkuId(transferDtl.getFmSku());
        trsnDtl.setQty(new BigDecimal(transferDtlUpdate.getCmpQty()));
        trsnDtl.setUnit(transferDtl.getUnit());
        trsnDtl.setInvAttr(transferDtl.getFmInvAttr());
        trsnDtl.setQaStatus(transferDtl.getFmQaStatus());
        trsnDtl.setStatus(TrsnDtlStatusEnum.CMP.code);
        trsnDtl.setComments(transferHeader.getTransferNo()+"调拨");
        trsnDtl.setCreateUser(loginName);
        trsnDtl.setCreateTime(trsnDate);
        trsnDtlMapper.insert(trsnDtl);
        fmTrsnDtlId=trsnDtl.getTrsnDtlId();
        trsnDtl.setTrsnHeaderId(trsnToHeader.getTrsnHeaderId());
        trsnDtl.setNoteNo(trsnToHeader.getNoteNo());
        trsnDtl.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.IN.code);
        trsnDtl.setSkuId(transferDtl.getToSku());
        trsnDtl.setInvAttr(transferDtl.getToInvAttr());
        trsnDtl.setQaStatus(transferDtl.getToQaStatus());
        trsnDtlMapper.insert(trsnDtl);
        toTrsnDtlId=trsnDtl.getTrsnDtlId();
        for (Goods goods : goodsList) {
            trsnDtlGoods.setTrsnDtlId(fmTrsnDtlId);
            trsnDtlGoods.setGoodsSn(goods.getGoodsSn());
            trsnDtlGoods.setGoodsId(goods.getGoodsId());
            trsnDtlGoods.setQty(goods.getQty());
            trsnDtlGoods.setQaStatus(transferDtl.getFmQaStatus());
            trsnDtlGoods.setComments(transferHeader.getTransferNo()+"调拨");
            trsnDtlGoods.setStatus(TrsnDtlGoodsStatusEnum.RECEIVED.getCode());
            trsnDtlGoods.setCreateUser(loginName);
            trsnDtlGoods.setCreateTime(trsnDate);
            trsnDtlGoodsMapper.insert(trsnDtlGoods);
            trsnDtlGoods.setTrsnDtlId(toTrsnDtlId);
            trsnDtlGoods.setQaStatus(transferDtl.getToQaStatus());
            trsnDtlGoodsMapper.insert(trsnDtlGoods);
        }

        return result;
    }

    //原材料库内调拨变更库存
    private void whsUpdateRepertory(String loginName, Date nowDate, List<Goods> goodsList, TransferHeader transferHeader,TransferDtl transferDtl, String transferType) throws Exception {
        Integer toWhs = transferHeader.getToWhs();
        //记录goods日志表
        Goods goodsUpdate = new Goods();
        GoodsLog goodsLog = new GoodsLog();
        String goodsJson;
        for (Goods goods : goodsList) {
            BeanUtil.copyNonNull(goods, goodsUpdate);
            goodsUpdate.setWhsId(transferHeader.getToWhs());
            goodsUpdate.setLocId(null);
            goodsUpdate.setOwner(transferDtl.getToOwner());
            goodsUpdate.setSkuId(transferDtl.getToSku());
            goodsUpdate.setFactory(transferDtl.getToFactory());
            goodsUpdate.setQaStatus(transferDtl.getToQaStatus());

            goodsLog.setGoodsSn(goods.getGoodsSn());
            goodsLog.setOpCode(OpCodeEnum.TRANSFER.getCode());
            goodsLog.setReason("调拨,出库单号["+transferHeader.getTransferNo()+"]");
            goodsJson="未更新的:" + JSON.toJSONString(goods)+ ",更新的:"+JSON.toJSONString(goodsUpdate);
            goodsLog.setUpdateContent(goodsJson);
            goodsLog.setOperator(loginName);
            goodsLog.setCreateUser(loginName);
            goodsLog.setCreateTime(new Date());
            goodsLog.setModifyUser(loginName);
            goodsLog.setModifyTime(new Date());
            goodsLogMapper.insert(goodsLog);
        }
        //变更库存
        Map<String, List<Goods>> updateInvCollect = goodsList.stream().collect(
                Collectors.groupingBy(t -> t.getWhsId() + "#" + t.getLocId() + "#" + t.getOwner() + "#" +
                        t.getSkuId() + "#" + t.getFactory() + "#" + t.getVendorId() + "#" + t.getLotno()
                        + "#" + t.getInvAttr() + "#" + t.getQaStatus(), Collectors.toList()));
        UpdateInventoryInputDto subInventoryInputDto = new UpdateInventoryInputDto();
        UpdateInventoryInputDto addInventoryInputDto = new UpdateInventoryInputDto();
        InvTrans invTrans = new InvTrans();
        for (Map.Entry<String, List<Goods>> entry : updateInvCollect.entrySet()) {
            BigDecimal qty = entry.getValue().stream().map(Goods::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
            this.setInventoryInputDto(entry.getValue(), loginName,qty.negate(),subInventoryInputDto);
            this.setInventoryInputDtoAdd(entry.getValue(), loginName,qty,addInventoryInputDto,transferHeader,transferDtl);
            addInventoryInputDto.setLocId(null);
            invTrans.setCreateTime(nowDate);
            invTrans.setCreateUser(loginName);
            invTrans.setOpCode(OperateCodeEnum.CREATE.getEnumName());//TODO 操作
            invTrans.setDocType(transferType);//单据类型
            invTrans.setDocNo(transferDtl.getTransferNo());//TODO 单据号==调拨单号？？
            invTrans.setStatus(InvTransStatusEnum.FINISHED.getCode()); //TODO 0 未完成，暂时写死 交易状态
            invTrans.setTransTime(nowDate);//TODO 交易时间
            invTrans.setOperator(loginName);
            invTrans.setFmOwner(subInventoryInputDto.getOwner());//TODO 货主
            invTrans.setFmSkuId(subInventoryInputDto.getSkuId());
            invTrans.setToWhsId(addInventoryInputDto.getWhsId());
            invTrans.setFmUnit(subInventoryInputDto.getUnit());
            invTrans.setFmQty(subInventoryInputDto.getQty());
            invTrans.setToOwner(addInventoryInputDto.getOwner());
            invTrans.setToSkuId(addInventoryInputDto.getSkuId());
            invTrans.setToWhsId(addInventoryInputDto.getWhsId());
            invTrans.setToUnit(addInventoryInputDto.getUnit());
            invTrans.setToQty(addInventoryInputDto.getQty());
            invTrans.setFmLocId(subInventoryInputDto.getLocId());
            invTrans.setDocLineNo(transferDtl.getTransferLineNo());//TODO 单据行号
            invTrans.setFmWhsId(subInventoryInputDto.getWhsId());//TODO 库存地点
            inventoryService.inventoryTransfer(subInventoryInputDto, addInventoryInputDto, invTrans);
        }
        List<Integer> goodsIds = goodsList.stream().map(t -> t.getGoodsId()).collect(Collectors.toList());
        //更新goods
        if (goodsIds.size() > 999) {
            List<List<Integer>> splitList = MyListUtil.splitList(goodsIds, 999);
            for (List<Integer> split : splitList) {
                if (split != null && split.size() > 0) {
                    List<Goods> goodsSplitList = goodsMapper.selectList(new QueryWrapper<Goods>().in("GOODS_SN", split));
                    goodsList.addAll(goodsSplitList);
                    transferAutoMapper.updateTransferGoods(split,toWhs,loginName,nowDate,transferDtl);
                }
            }
        } else {
            transferAutoMapper.updateTransferGoods(goodsIds,toWhs,loginName,nowDate,transferDtl);
        }
    }


    //生成库存信息
    private UpdateInventoryInputDto setInventoryInputDto(
            List<Goods> goodsList,String loginName,BigDecimal qty,UpdateInventoryInputDto inventoryInputDto){
        inventoryInputDto.setWhsId(goodsList.get(0).getWhsId());
        inventoryInputDto.setLocId(goodsList.get(0).getLocId());
        inventoryInputDto.setOwner(goodsList.get(0).getOwner());
        inventoryInputDto.setSkuId(goodsList.get(0).getSkuId());
        inventoryInputDto.setFactory(goodsList.get(0).getFactory());
        inventoryInputDto.setVendorId(goodsList.get(0).getVendorId());
        inventoryInputDto.setLotNo(goodsList.get(0).getLotno());
        inventoryInputDto.setInvAttr(goodsList.get(0).getInvAttr());
        inventoryInputDto.setQaStatus(goodsList.get(0).getQaStatus());
        inventoryInputDto.setOperator(loginName);
        inventoryInputDto.setQty(qty);
        inventoryInputDto.setUnit(goodsList.get(0).getUnit());
        return inventoryInputDto;
    }

    private UpdateInventoryInputDto setInventoryInputDtoAdd(
            List<Goods> goodsList,String loginName,BigDecimal qty,UpdateInventoryInputDto inventoryInputDto,
            TransferHeader transferHeader,TransferDtl transferDtl){
        inventoryInputDto.setWhsId(transferHeader.getToWhs());
        inventoryInputDto.setLocId(null);
        inventoryInputDto.setOwner(transferDtl.getToOwner());
        inventoryInputDto.setSkuId(transferDtl.getToSku());
        inventoryInputDto.setFactory(transferDtl.getToFactory());
        inventoryInputDto.setVendorId(goodsList.get(0).getVendorId());
        inventoryInputDto.setLotNo(goodsList.get(0).getLotno());
        inventoryInputDto.setInvAttr(goodsList.get(0).getInvAttr());
        inventoryInputDto.setQaStatus(transferDtl.getToQaStatus());
        inventoryInputDto.setOperator(loginName);
        inventoryInputDto.setQty(qty);
        inventoryInputDto.setUnit(goodsList.get(0).getUnit());
        return inventoryInputDto;
    }

    private void setGdnHeader(GdnHeader gdnHeader,TransferHeader transferHeader,TransferDtl transferDtl,String loginName){
        String gdnNo = this.basicSimpleCodeRuleApi.GenerateCode(GDN_D16);
        gdnHeader.setGdnNo(gdnNo);
        gdnHeader.setGdnType(GdnTypeEnum.D16.code);
        gdnHeader.setSourceShipNotice(transferHeader.getTransferNo());
        gdnHeader.setOwner(transferDtl.getToOwner());
        gdnHeader.setFactory(transferDtl.getToFactory());
        gdnHeader.setDataSource(transferHeader.getTransferNo());
        gdnHeader.setComments("报废出库");
        gdnHeader.setStatus(GdnHeaderStatusEnum.CREATE.code);
        gdnHeader.setCreateUser(loginName);
        gdnHeader.setCreateTime(new Date());
    }

    private void checkSnEqualTransfer(Goods goods, TransferDtl transferDtl, TransferHeader transferHeader) {
        //调拨单信息(调拨单明细表)	SN信息(货品清单表)

        //调拨单类型
        String transferType = transferHeader.getTransferType();

        //来源货品	货品
        //仓库	仓库
        //来源货主	货主
        //来源工厂(组织)	工厂代码(组织)
        //来源供应商	供应商
        //来源库存性质	库存性质
        //来源货品品质状态	品质状态
        //来源订单号	采购订单
        //转出销售订单	销售订单
        //转出销售订单项目	销售订单行号
        //若字段数据一致，则校验通过，把产品SN返回，加入到【未提交SN】列表

        boolean flagSKu = Objects.equals(goods.getSkuId(), transferDtl.getFmSku());//货品
        if (!flagSKu) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的货品与调拨单的不一致，录入失败");
        }
        boolean flagWhs = Objects.equals(goods.getWhsId(), transferHeader.getFmWhs());//仓库
        if (!flagWhs) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的仓库与调拨单的不一致，录入失败");
        }
        boolean flagOwner = Objects.equals(goods.getOwner(), transferDtl.getFmOwner());//货主
        if (!flagOwner) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的货主与调拨单的不一致，录入失败");
        }
        boolean flagFactory = Objects.equals(goods.getFactory(), transferDtl.getFmFactory());//工厂代码(组织)
        if (!flagFactory) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的工厂代码（组织）与调拨单的不一致，录入失败");
        }
        //TODO ZYF:原材料不校验供应商
      /*  boolean flagVendor = Objects.equals(goods.getVendorId(), transferDtl.getFmVendor());//供应商
        if (!flagVendor) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的供应商与调拨单的不一致，录入失败");
        }*/
        boolean flagInvAttr = Objects.equals(goods.getInvAttr(), transferDtl.getFmInvAttr());//库存性质
        if (!flagInvAttr) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的库存性质与调拨单的不一致，录入失败");
        }
        boolean flagQaStatus = Objects.equals(goods.getQaStatus(), transferDtl.getFmQaStatus());//品质状态

        //借还机不校验QAstatus
        if ((!transferType.equals(TransferTypeEnum.T06.getCode())) && (!transferType.equals(TransferTypeEnum.T05.getCode()))) {
            if (!flagQaStatus) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的品质状态与调拨单的不一致，录入失败");
            }
        }

        //原先有采购订单校验
//        boolean flagPo = Objects.equals(goods.getPoNo(), transferDtl.getFmPo());//采购订单
//        if (!flagPo) {
//            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的采购订单与调拨单的不一致，录入失败");
//        }
        if (transferDtl.getFmLotno() != null) {
            boolean flagLotno = Objects.equals(goods.getLotno(), transferDtl.getFmLotno());//批次号
            if (!flagLotno) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的批次号与调拨单的不一致，录入失败");
            }

        } else {
            //批次号为NULL则验证字段
            boolean flagSo = Objects.equals(goods.getSoNo(), transferDtl.getFmSoNo());//销售订单
            if (!flagSo) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的销售订单与调拨单的不一致，录入失败");
            }
            boolean flagSoItem = Objects.equals(goods.getSoItem(), transferDtl.getFmSoLineNo());//销售订单行号
            if (!flagSoItem) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的销售订单行号与调拨单的不一致，录入失败");
            }
        }

    }

    /**
     * 调拨单管理列表BS
     *
     * @param dto
     * @return
     */
    public PagerInfo<List<TransferRawResponse>> searchTransferRaw(
            SearchTransferTaskRequest dto, Pager<?> pager) {
        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<List<TransferRawResponse>> pagerInfo = new PagerInfo<>();

        Date beginDate = null, endDate = null;
        if(dto.getBeginTime() != null) {
            beginDate = DateUtils.getStartTime(dto.getBeginTime());
        }
        if(dto.getEndTime() != null) {
            endDate = DateUtils.getEndTime(dto.getEndTime());
        }

        if (dto.getTransferDeptName() != null) {
            dto.setTransferDeptName(StringUtils.decode(dto.getTransferDeptName()));
        }
        List<TransferRawResponse> list = transferHeaderMapper.getListTransferRaw(dto,
                transferTypeList, transferAllStatusList, beginDate, endDate);
        pagerInfo.setItems(list);
        pagerInfo.setTotalCount(page.getTotal());
        return pagerInfo;
    }

    /**
     * 调拨单管理细列表BS
     *
     * @param transferHeaderId
     * @return
     */
    public List<TransferRawDtlResponse> searchTransferRawDtl(
            Integer transferHeaderId) {
        List<TransferRawDtlResponse> listTransferTaskDtl = transferDtlMapper.getListTransferRawDtl(transferHeaderId);

        //根据行号排个序
        listTransferTaskDtl = listTransferTaskDtl.stream().sorted(Comparator.comparing(TransferRawDtlResponse::getTransferLineNo)).collect(Collectors.toList());

        return listTransferTaskDtl;
    }

    //查询入库凭证单据类型下拉框
    public List<OrtherAsnEnums> getTransferRawEnumsList(){
        List<OrtherAsnEnums> datas=new ArrayList<>();
        for (String transferTypeString : transferTypeList) {
            TransferTypeEnum transferTypeEnum = TransferTypeEnum.getEnumByCode(transferTypeString);
            if (transferTypeEnum!=null){
                OrtherAsnEnums data=new OrtherAsnEnums();
                data.setCode(transferTypeString);
                data.setEnumName(transferTypeEnum.getEnumName());
                datas.add(data);
            }
        }
        return datas;
    }

    /**
     * 导出调拨单
     * @param dto
     * @param request
     * @param response
     * @throws Exception
     */
    public void exportTransferReportList(SearchTransferTaskRequest dto, HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        Date beginDate = null, endDate = null;
        if(dto.getBeginTime() != null) {
            beginDate = DateUtils.getStartTime(dto.getBeginTime());
        }
        if(dto.getEndTime() != null) {
            endDate = DateUtils.getEndTime(dto.getEndTime());
        }

        if (dto.getTransferDeptName() != null) {
            dto.setTransferDeptName(StringUtils.decode(dto.getTransferDeptName()));
        }
        List<TransferRawResponse> dataSet = transferHeaderMapper.getListTransferRaw(dto, transferTypeList, transferAllStatusList, beginDate, endDate);

        ExportParams params = new ExportParams();
        params.setType(ExcelType.XSSF);
        params.setHeight((short)5);
        Workbook workbook = ExcelExportUtil.exportExcel(params, TransferRawResponse.class, dataSet);

        String fileName = "原材料调拨单";
        HttpExcel.downLoadExcel(fileName, workbook, request, response);
    }



    //生成出库凭证单头
    private void setFmTrsnHeader(TransferHeader transferHeader,TransferDtl dtl,TrsnHeader trsnHeader,String loginName){
        String noteNo = this.basicSimpleCodeRuleApi.GenerateCode(TRSN_ORDER);
        trsnHeader.setNoteNo(noteNo);
        trsnHeader.setNoteType(TrsnNoteTypeEnum.ADJUST_STORAGE.getCode());
        trsnHeader.setOwner(dtl.getFmOwner());
        trsnHeader.setFactory(dtl.getFmFactory());
        trsnHeader.setVendorId(dtl.getFmVendor());
        trsnHeader.setWhsId(transferHeader.getFmWhs());
        trsnHeader.setFmDoc(transferHeader.getTransferNo());
        trsnHeader.setStatus(TrsnHeaderStatusEnum.CMP.code);
        trsnHeader.setCreateTime(new Date());
        trsnHeader.setCreateUser(loginName);
    }

    private void setToTrsnHeader(TransferHeader transferHeader,TransferDtl dtl,TrsnHeader trsnHeader,String loginName){
        String noteNo = this.basicSimpleCodeRuleApi.GenerateCode(TRSN_ORDER);
        trsnHeader.setNoteNo(noteNo);
        trsnHeader.setNoteType(TrsnNoteTypeEnum.ADJUST_STORAGE.getCode());
        trsnHeader.setOwner(dtl.getToOwner());
        trsnHeader.setFactory(dtl.getToFactory());
        trsnHeader.setVendorId(dtl.getToVendor());
        trsnHeader.setFmDoc(transferHeader.getTransferNo());
        trsnHeader.setStatus(TrsnHeaderStatusEnum.CMP.code);
        trsnHeader.setCreateTime(new Date());
        trsnHeader.setCreateUser(loginName);
        trsnHeader.setWhsId(transferHeader.getToWhs());
    }





}
